/* eslint-disable */
import context from '@/main.js'
import store from '@/vuex/index.js'
import dates from '@/util/dates.js'
import crypto from 'crypto'
import { Message } from 'element-ui'
import {Toast} from "vant";

const utils = {
  // 外壳程序支持
  commonShellInvokeJs(para) {
    let errMessage = `收到外壳调用请求：${para.action}，但是需要HTML页面先登录WEB系统。`
    Message({ message: errMessage, type: 'error', showClose: true, duration: 0 })
    return {
      success: false,
      message: errMessage
    }
  },
  // 回调转异步
  promisify(func, ctx) {
    // 返回一个新的function
    return function() {
      // 初始化this作用域
      var ctx = ctx || this
      // 新方法返回的promise
      return new Promise((resolve, reject) => {
        // 调用原来的非promise方法func，绑定作用域，传参，以及callback（callback为func的最后一个参数）
        func.call(ctx, ...arguments, function() {
          // 将回调函数中的的第一个参数error单独取出
          var args = Array.prototype.map.call(arguments, item => item)
          var err = args.shift()
          // 判断是否有error
          if (err) {
            reject(err)
          } else {
            // 没有error则将后续参数resolve出来
            args = args.length > 1 ? args : args[0]
            resolve(args)
          }
        })
      })
    }
  },
  // 克隆JSON对象
  jsonClone(obj) {
    const str = obj.constructor === String ? obj : JSON.stringify(obj)
    return JSON.parse(str)
  },
  // 驼峰转下划线
  toUnderlineName(oriName) {
    return oriName.replace(/([A-Z])/g, '_$1').toLowerCase()
  },
  // 下划线转驼峰
  toHump(name) {
    return name.replace(/\_(\w)/g, (all, letter) => letter.toUpperCase())
  },
  // md5加密
  md5(str) {
    const md5 = crypto.createHash('md5')
    md5.update(str)
    return md5.digest('hex')
  },
  // 随机编码（指定长度）
  randomCode(len) {
    return this.md5(new Date().toString() + Math.random().toString()).substring(0, len)
  },
  uuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
      const r = (Math.random() * 16) | 0
      const v = c == 'x' ? r : (r & 0x3) | 0x8
      return v.toString(16)
    })
  },
  sleep(ms) {
    const _sleep = ms => new Promise((r, j) => setTimeout(r, ms))
    ;(async () => {
      await _sleep(ms)
    })()
  },
  /**
   * 树形结构查找
   * @param {Array} src:查找的源对象数组
   * @param {Function} cb:回调函数，回调的参数为源对象
   * @param {String} childName:儿子节点名称，默认children
   */
  findTreeNode(src, cb, childName = 'children') {
    const foundResult = []
    src.forEach(item => {
      if (cb(item)) {
        foundResult.push(item)
      }
      item.children && foundResult.push(...this.findTreeNode(item[childName], cb))
    })
    return foundResult
  },
  openMenu(routeName, params) {
    const menus = store.getters.menuGetter
    const foundMenus = this.findTreeNode(menus, m => m.route == routeName) || []
    if (foundMenus.length == 0) {
      throw new Error('未找到路由名称')
    }
    const menu = foundMenus[0]
    vue.$router.replace({ name: menu.route, params }).catch(() => null)
  },
  /**
   * 打开自定义的窗口
   * @param {Object} options : {routeName: '全局唯一', url: '/sys/wi/index.vue', para: {pk: '1212121212'}}
   */
  openForm(options) {
    const routeName = options.routeName
    const url = options.url
    if (!routeName || !url) {
      throw new Error('请指定路由名称和URL')
    }
    const routes = context.$router.options.routes
    const foundRoutes= this.findTreeNode(routes, r => r.name == routeName) || []
    let route = {}
    if (foundRoutes.length == 0) {
      route = context.$router.options.routes[1]
      route.children = []
      route.children.push({
        path: `${routeName}/`,
        name: routeName,
        component: require([`@/views/${url}`] ),
        meta: {
          requireAuth: true,
          title: options.title || '页面'
        }
      })
      context.$router.addRoutes([route])
    } else {
      route = foundRoutes[0]
    }
    context.$router.push({ name: routeName, params: options })
  },
  /* 给出行数据和配置，生成树形的数据结构
   *  data:数据源，
   *  config 可配置根节点（不配置，默认第一条），key字段名，label字段名,示例：
   * { rootNode: {id:1, parentId:0, name:'根节点' }, keyFieldName: 'id', parentFieldName: 'parentId', labelFieldName: 'name'}
   */
  convertToTree(data, config) {
    const tree = []
    let rootNode = {}
    // 未指定根节点信息，读取第一条数据作为根节点
    if (config.rootNode) {
      rootNode = config.rootNode
      rootNode.label = rootNode.label || rootNode[config.labelFieldName]
    } else {
      if (data.length < 1) {
        rootNode[config.keyFieldName] = -1
        rootNode.label = '无数据'
      } else {
        rootNode[config.keyFieldName] = data[0][config.keyFieldName]
        rootNode.label = data[0][config.labelFieldName]
      }
    }
    rootNode.children = this._getTreeChildren(rootNode, data, config, 0)
    tree.push(rootNode)
    return tree
  },
  _getTreeChildren(parentNode, data, config, level) {
    level += 1
    const children = []
    const childArr = data.filter(item => {
      return item[config.parentFieldName] == parentNode[config.keyFieldName]
    })
    if (childArr.length < 1) return null
    childArr.forEach((currentValue, index, arr) => {
      const node = {}
      node[config.keyFieldName] = currentValue[config.keyFieldName]
      node.label = currentValue[config.labelFieldName]
      node.meta = currentValue
      node.level = level
      node.children = this._getTreeChildren(currentValue, data, config, level)
      children.push(node)
    })
    return children
  },
  // == end ==
  /**
   * 获取字典标签
   * @param {String} value
   * @param {String} type
   * @param {*} defaultValue
   */
  getDictLabel(value, type, defaultValue, showColor = true) {
    if (value === undefined || value === null || value === '' || type === undefined || type === null || type === '') {
      return defaultValue
    }

    let dictDataList = store.getters.dictDataMap.get(type)
    for (const index in dictDataList) {
      let d = dictDataList[index]

      if (d.dictTypeCode == type && d.value == value) {
        let label = d.label
        return showColor ? `<span style="color:${d.color}">${label}</span>` : label
      }
    }
    return defaultValue
  },
  getDictDataList(type) {
    return store.getters.dictDataMap.get(type)
  },
  now() {
    return new Date().format('yyyy/MM/dd hh:mm:ss')
  },
  getStringParam(key, defaultValue) {
    let value = store.getters.parameterMap.get(key)
    return value ? value : defaultValue
  },
  getBooleanParam(key, defaultValue = false) {
    let value = store.getters.parameterMap.get(key)
    if (strings.isBlank(value)) {
      return defaultValue
    }
    return value == '1'
  },
  getCurrentUser() {
    return store.getters.currentUser
  },
  //获取当前所设置的工位
  getCurrentWarehouse() {
    return store.getters.currentWarehouse
  },
  isObject(item) {
    return item && typeof item === 'object' && !Array.isArray(item)
  },
  mergeDeep(target, ...sources) {
    if (!sources.length) return target

    const source = sources.shift()
    if (this.isObject(target) && this.isObject(source)) {
      for (const key in source) {
        if (!target[key]) {
          Object.assign(target, {
            [key]: source[key]
          })
          continue
        }

        if (Array.isArray(source[key])) {
          if (this.isObject(target[key])) {
            Object.assign(target, {
              [key]: source[key]
            })
          } else {
            for (let i = 0; i < source[key].length; i++) {
              let sourceValueType = typeof source[key][i]
              if (['string', 'number'].includes(sourceValueType)) {
                target[key][i] = source[key][i]
              } else {
                this.mergeDeep(target[key][i], source[key][i])
              }
            }
          }
          continue
        }

        if (this.isObject(source[key])) {
          if (Array.isArray(target[key])) {
            Object.assign(target, {
              [key]: source[key]
            })
            continue
          }
          this.mergeDeep(target[key], source[key])
        }
      }
    }
    return this.mergeDeep(target, ...sources)
  },
  loadShow() {
    Toast.loading()
  },
  loadHide() {
    Toast.clear()
  },

  /** 振动，如果支持的话
  * @param time 振动时间，毫秒，默认 100毫秒
  */
  vibrate (time) {
    navigator.vibrate = navigator.vibrate ||
      navigator.webkitVibrate ||
      navigator.mozVibrate ||
      navigator.msVibrate
    if(navigator.vibrate) {
      if (!time) time = 100
      navigator.vibrate(time);
    }
  },

  /** 扫描 聚焦文本框，清除数据
   */
  clearFocus (that, refKey, valueKey) {
    that[valueKey] = ''
    setTimeout(() => {
      that.$refs[refKey].focus()
    }, 500)
  }
}
export default utils
